//! # 观测性集成示例
//! 
//! 展示如何在RustCloud框架中集成和使用统一的观测性接口

use rustcloud::prelude::*;
use rustcloud::observability::*;
use rustcloud_metrics::MemoryMetricsCollector;
use std::sync::Arc;
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化日志
    tracing_subscriber::init();

    // 创建观测性配置
    let mut observability_config = ObservabilityConfig::default();
    observability_config.default_labels.insert("service".to_string(), "demo".to_string());
    observability_config.default_labels.insert("version".to_string(), "1.0.0".to_string());
    observability_config.sampling.trace_sampling_rate = 1.0; // 100%采样，仅用于演示

    // 创建观测性管理器
    let observability = Arc::new(
        ObservabilityManager::new(observability_config)
            .with_metrics_collector(Arc::new(MemoryMetricsCollector::new()))
            .with_tracing_processor(Arc::new(MockTracingProcessor::new()))
            .with_log_manager(Arc::new(MockLogManager::new()))
    );

    println!("🔍 RustCloud 统一观测性演示");
    println!("================================");

    // 1. 基础观测性操作演示
    demo_basic_observability(observability.clone()).await?;

    // 2. 上下文管理演示
    demo_context_management(observability.clone()).await?;

    // 3. 错误处理演示
    demo_error_handling(observability.clone()).await?;

    // 4. 指标收集演示
    demo_metrics_collection(observability.clone()).await?;

    // 5. 中间件使用演示
    demo_middleware_usage(observability.clone()).await?;

    // 6. 批量导出演示
    demo_batch_export(observability.clone()).await?;

    println!("\n✅ 观测性演示完成");
    Ok(())
}

/// 基础观测性操作演示
async fn demo_basic_observability(observability: Arc<ObservabilityManager>) -> ServiceResult<()> {
    println!("\n📋 1. 基础观测性操作演示");
    
    // 启动操作上下文
    let context_id = observability.start_context(
        "demo-service".to_string(),
        "basic_operation".to_string()
    ).await?;

    // 记录一些活动
    observability.log_info("执行基础操作", None).await?;
    
    // 添加上下文属性
    observability.add_context_attribute(
        &context_id,
        "user_id".to_string(),
        serde_json::Value::String("user123".to_string())
    ).await?;

    // 模拟一些工作
    tokio::time::sleep(std::time::Duration::from_millis(100)).await;

    // 结束上下文
    observability.end_context(&context_id).await?;

    println!("   ✅ 基础操作完成");
    Ok(())
}

/// 上下文管理演示
async fn demo_context_management(observability: Arc<ObservabilityManager>) -> ServiceResult<()> {
    println!("\n🔗 2. 上下文管理演示");

    // 父操作
    let parent_context_id = observability.start_context(
        "demo-service".to_string(),
        "parent_operation".to_string()
    ).await?;

    observability.log_info("开始父操作", None).await?;

    // 子操作1
    let child1_context_id = observability.start_context(
        "demo-service".to_string(),
        "child_operation_1".to_string()
    ).await?;

    observability.add_trace_event(
        &child1_context_id,
        "processing_data",
        {
            let mut attrs = HashMap::new();
            attrs.insert("data_size".to_string(), serde_json::Value::Number(serde_json::Number::from(1024)));
            attrs
        }
    ).await?;

    tokio::time::sleep(std::time::Duration::from_millis(50)).await;
    observability.end_context(&child1_context_id).await?;

    // 子操作2
    let child2_context_id = observability.start_context(
        "demo-service".to_string(),
        "child_operation_2".to_string()
    ).await?;

    tokio::time::sleep(std::time::Duration::from_millis(75)).await;
    observability.end_context(&child2_context_id).await?;

    // 结束父操作
    observability.log_info("完成父操作", None).await?;
    observability.end_context(&parent_context_id).await?;

    println!("   ✅ 上下文管理演示完成");
    Ok(())
}

/// 错误处理演示
async fn demo_error_handling(observability: Arc<ObservabilityManager>) -> ServiceResult<()> {
    println!("\n❌ 3. 错误处理演示");

    let context_id = observability.start_context(
        "demo-service".to_string(),
        "error_operation".to_string()
    ).await?;

    observability.log_info("开始可能失败的操作", None).await?;

    // 模拟错误
    observability.record_error(&context_id, "模拟的业务错误").await?;

    observability.end_context(&context_id).await?;

    println!("   ✅ 错误处理演示完成");
    Ok(())
}

/// 指标收集演示
async fn demo_metrics_collection(observability: Arc<ObservabilityManager>) -> ServiceResult<()> {
    println!("\n📊 4. 指标收集演示");

    let mut labels = HashMap::new();
    labels.insert("endpoint".to_string(), "/api/users".to_string());
    labels.insert("method".to_string(), "GET".to_string());

    // 记录各种类型的指标
    observability.record_counter("http_requests_total", 1.0, labels.clone()).await?;
    observability.record_gauge("active_connections", 42.0, HashMap::new()).await?;
    observability.record_histogram("request_duration_seconds", 0.123, labels.clone()).await?;

    // 业务指标
    let mut business_labels = HashMap::new();
    business_labels.insert("operation".to_string(), "user_creation".to_string());
    observability.record_counter("business_operations_total", 1.0, business_labels).await?;

    println!("   ✅ 指标收集演示完成");
    Ok(())
}

/// 中间件使用演示
async fn demo_middleware_usage(observability: Arc<ObservabilityManager>) -> ServiceResult<()> {
    println!("\n🔧 5. 中间件使用演示");

    let middleware = ObservabilityMiddleware::new(observability.clone(), "demo-service".to_string());

    // 使用中间件包装操作
    let result = middleware.wrap_operation("middleware_operation", async {
        tokio::time::sleep(std::time::Duration::from_millis(100)).await;
        Ok::<String, ServiceError>("操作成功".to_string())
    }).await?;

    println!("   操作结果: {}", result);

    // 演示失败的操作
    let _error_result = middleware.wrap_operation("failing_operation", async {
        Err::<(), ServiceError>(ServiceError::InternalError("模拟失败".to_string()))
    }).await;

    println!("   ✅ 中间件使用演示完成");
    Ok(())
}

/// 批量导出演示
async fn demo_batch_export(observability: Arc<ObservabilityManager>) -> ServiceResult<()> {
    println!("\n📤 6. 批量导出演示");

    // 生成一些数据
    for i in 0..5 {
        let context_id = observability.start_context(
            "demo-service".to_string(),
            format!("batch_operation_{}", i)
        ).await?;

        observability.record_counter("batch_operations_total", 1.0, HashMap::new()).await?;
        
        tokio::time::sleep(std::time::Duration::from_millis(10)).await;
        observability.end_context(&context_id).await?;
    }

    // 导出所有数据
    observability.export_all().await?;

    println!("   ✅ 批量导出演示完成");
    
    // 显示统计信息
    let active_count = observability.get_active_contexts_count().await;
    println!("   活动上下文数量: {}", active_count);

    // 清理过期上下文
    let cleaned = observability.cleanup_expired_contexts(std::time::Duration::from_secs(1)).await?;
    println!("   清理的过期上下文: {}", cleaned);

    Ok(())
}

/// 模拟追踪处理器
struct MockTracingProcessor {
    spans: Arc<tokio::sync::RwLock<Vec<String>>>,
}

impl MockTracingProcessor {
    fn new() -> Self {
        Self {
            spans: Arc::new(tokio::sync::RwLock::new(Vec::new())),
        }
    }
}

#[async_trait::async_trait]
impl TracingProcessor for MockTracingProcessor {
    async fn start_span(&self, context: &ObservabilityContext) -> ServiceResult<()> {
        let mut spans = self.spans.write().await;
        spans.push(format!("START: {} [{}]", context.operation_name, context.span_id));
        println!("   🔍 追踪: 开始 Span '{}' (ID: {})", context.operation_name, context.span_id);
        Ok(())
    }

    async fn end_span(&self, context: &ObservabilityContext) -> ServiceResult<()> {
        let mut spans = self.spans.write().await;
        spans.push(format!("END: {} [{}] ({}ms)", 
            context.operation_name, 
            context.span_id, 
            context.duration().as_millis()
        ));
        println!("   🔍 追踪: 结束 Span '{}' (时长: {}ms)", context.operation_name, context.duration().as_millis());
        Ok(())
    }

    async fn add_event(&self, context: &ObservabilityContext, name: &str, attributes: HashMap<String, serde_json::Value>) -> ServiceResult<()> {
        println!("   🔍 追踪: 添加事件 '{}' 到 Span '{}' (属性: {:?})", name, context.operation_name, attributes);
        Ok(())
    }

    async fn export(&self) -> ServiceResult<()> {
        let spans = self.spans.read().await;
        println!("   📤 导出 {} 个追踪数据", spans.len());
        Ok(())
    }
}

/// 模拟日志管理器
struct MockLogManager {
    logs: Arc<tokio::sync::RwLock<Vec<String>>>,
}

impl MockLogManager {
    fn new() -> Self {
        Self {
            logs: Arc::new(tokio::sync::RwLock::new(Vec::new())),
        }
    }
}

#[async_trait::async_trait]
impl LogManager for MockLogManager {
    async fn log(&self, level: LogLevel, message: &str, context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        let mut logs = self.logs.write().await;
        let log_entry = if let Some(ctx) = context {
            format!("[{:?}] {} (trace: {}, span: {})", level, message, ctx.trace_id, ctx.span_id)
        } else {
            format!("[{:?}] {}", level, message)
        };
        logs.push(log_entry.clone());
        println!("   📝 日志: {}", log_entry);
        Ok(())
    }

    async fn log_structured(&self, level: LogLevel, message: &str, fields: HashMap<String, serde_json::Value>, context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        let mut logs = self.logs.write().await;
        let fields_str = serde_json::to_string(&fields).unwrap_or_default();
        let log_entry = if let Some(ctx) = context {
            format!("[{:?}] {} {} (trace: {}, span: {})", level, message, fields_str, ctx.trace_id, ctx.span_id)
        } else {
            format!("[{:?}] {} {}", level, message, fields_str)
        };
        logs.push(log_entry.clone());
        println!("   📝 结构化日志: {}", log_entry);
        Ok(())
    }

    async fn export(&self) -> ServiceResult<()> {
        let logs = self.logs.read().await;
        println!("   📤 导出 {} 条日志", logs.len());
        Ok(())
    }
}